﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace CarRace
{
    public struct Position
    {
        public float x;
        public float y;
        public Position(float x, float y)
        {
            this.x = x;
            this.y = y; 
        }
    }

    public class Controller
    {
        public List<Terminal> terminals;
        public Cloud MessageCloud = new Cloud();
        //Car[] cars = new Car[3];
        World world = new World(); 
        Camera camera = new Camera();
        public List<Car> cars = new List<Car>();
        List<Streetlight> streetlights = new List<Streetlight>();
        Road road = new Road();
        Road road2 = new Road();
        Road road3 = new Road();
        Road road4 = new Road();
        static bool startedRace;
        static int winner = -1;
        // TESTE
        public bool StopTeste = false;

        public static int Winner
        {
            get { return Controller.winner; }
            set { Controller.winner = value; }
        }

        static bool finishedRace;

        public static bool FinishedRace
        {
            get { return Controller.finishedRace; }
            set { Controller.finishedRace = value; }
        }

        public static bool StartedRace
        {
            get { return Controller.startedRace; }
            set { Controller.startedRace = value; }
        }

        public Controller()
        {
            terminals = new List<Terminal>();
            //comF.Show();
            //for (int i = 0; i < cars.Length; i++)
            //{
            //    cars[i] = new Car();   
            //} 
        }

        public Position GetCarPosition(int ind)
        {
            return cars[ind].GetPosition();
        }

        public Camera Camera
        {
            get { return camera; }
        }

        public float GetDistanceInMeters(int carro)
        {
            return cars[carro].TraveledDistance * -1.5f;
            // Original value was 10, however a regular car has 3.75m of length, and the 3D cars
            // are represented by 2.5f. Then, 1f is equivalent of 1.5m.
        }

        public void ResetRace()
        {
            startedRace = false;
            finishedRace = false; 
            for (int i = 0; i < cars.Count; i++)
            {
                cars[i].ResetRace(); 
            }
        }

        public void CreateObjects(int selectedScenario)
        {
            // Scenario 1 = crossing streetlight
            // Scenario 2 = crossing intersection with no streetlight
            if (selectedScenario == 2) cars.Add(new Car(2, new Position(50, -77), 90f, Color.Blue, 0.4f, 0, MessageCloud));
            if(selectedScenario == 1) cars.Add(new Car(2, new Position(1, 12.5f), 0, Color.Blue, 0, 0.2f, MessageCloud));
            cars.Add(new Car(1, new Position(3, 10), 0, Color.Red, 0, 0.75f, MessageCloud));
            //teste cars.Add(new Car(3, new Position(3, -30), 90f, Color.Red, 0, 0f, MessageCloud));
            if (selectedScenario == 1) cars.Add(new Car(3, new Position(1, 7.5f), 0, Color.Black, 0, 0.2f, MessageCloud));

            if (selectedScenario == 1) streetlights.Add(new Streetlight(new Position(2, -76), 0, 10));
            road.Create(0, 0,-140, false);
            road2.Create(-6, 0, -140, false);
            road3.Create(150, 0, -80, true);
            road4.Create(150, 0, -86, true);
        }

        public bool CheckCollision()
        {
            float car_width = 1f;
            float car_height = 2.5f;
            for (int i = 0; i < cars.Count-1; i++)
            {
                Position car = cars[i].GetPosition();
                Position[] vertex = new Position[4];
                vertex[0] = new Position(car.x - car_width / 2, car.y - car_height / 2);
                vertex[1] = new Position(car.x + car_width / 2, car.y - car_height / 2);
                vertex[2] = new Position(car.x - car_width / 2, car.y + car_height / 2);
                vertex[3] = new Position(car.x + car_width / 2, car.y + car_height / 2);
                for (int j = i + 1; j < cars.Count; j++)
                {
                    for (int k = 0; k < vertex.Length; k++)
                    {
                        Position thiscar = cars[j].GetPosition();
                        if (vertex[k].x <= thiscar.x + car_width / 2 && vertex[k].x >= thiscar.x - car_width / 2
                            && vertex[k].y <= thiscar.y + car_height / 2 && vertex[k].y >= thiscar.y - car_height / 2)
                        {
                            //MessageBox.Show("a");
                            if (!StopTeste)
                            {
                                StopTeste = true;
                                //CommunicateForm comF = new CommunicateForm();
                                //comF.Show();
                                //comF.SendData(car.x + ", " + car.y + "\n");
                                //comF.SendData(vertex[0].x + ", " + vertex[0].y + "\n");
                                //comF.SendData(vertex[1].x + ", " + vertex[1].y + "\n");
                                //comF.SendData(vertex[2].x + ", " + vertex[2].y + "\n");
                                //comF.SendData(vertex[3].x + ", " + vertex[3].y + "\n");
                                //comF.SendData(thiscar.x + ", " + thiscar.y + "\n");
                            }
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        public void DrawScene()
        {
            //draw the world (sky  & terrain)
            world.Draw();
            //draw the road
            road.Draw();
            road2.Draw();
            road3.Draw();
            road4.Draw();
            // draw streetlights;
            foreach (Streetlight element in streetlights)
            {
                element.Draw();
            }
  
            //draw cars
            foreach (Car element in cars)
            {
                element.Draw(StopTeste);
            }
        }
    }
}
